package com.dlc.shop.api.controller;


import com.alibaba.fastjson.JSON;
import com.dlc.shop.allinpay.config.AllinpayConfig;
import com.dlc.shop.allinpay.service.AllinpayCompanyService;
import com.dlc.shop.allinpay.service.AllinpayOrderService;
import com.dlc.shop.bean.model.UserExtension;
import com.dlc.shop.common.allinpay.bean.OpenRequest;
import com.dlc.shop.common.allinpay.constant.AllinpayConstant;
import com.dlc.shop.common.allinpay.constant.AllinpayPayStatus;
import com.dlc.shop.common.allinpay.member.resp.*;
import com.dlc.shop.common.allinpay.order.req.GetOrderStatusReq;
import com.dlc.shop.common.allinpay.order.resp.GetOrderStatusResp;
import com.dlc.shop.common.allinpay.order.resp.OrderResultNotice;
import com.dlc.shop.dao.ShopDetailMapper;
import com.dlc.shop.service.*;
import io.swagger.v3.oas.annotations.Hidden;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.Objects;

/**
 * 通联通知回调
 * @author lanhai
 */
@Hidden
@RestController
@RequestMapping("/notice/allinpay/member")
@AllArgsConstructor
public class AllinpayNoticeController {

    private static final Logger logger = LoggerFactory.getLogger(AllinpayNoticeController.class);

    private final AllinpayConfig allinpayConfig;

    private final AllinpayOrderService allinpayOrderService;
    private final UserExtensionService userExtensionService;
    private final UserWithdrawCashService userWithdrawCashService;
    private final AllinpayCompanyService allinpayCompanyService;
    private final CompanyAuditingService companyAuditingService;
    private final ShopDetailService shopDetailService;
    private final ShopWithdrawCashService shopWithdrawCashService;
    private final ShopDetailMapper shopDetailMapper;

    /**
     * 设置企业信息回调
     */
    @RequestMapping("/setCompanyInfoResult")
    public ResponseEntity<String> setCompanyResult(HttpServletRequest request,
                                                   @RequestBody(required = false) String data) throws UnsupportedEncodingException {
        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("企业信息回调:{}", openRequest.getBizContent());
        return ResponseEntity.ok(AllinpayConstant.NOTICE_SUCCESS);
    }

    /**
     * 修改企业信息回调
     * 企业信息修改后，系统准实时触发营业执照及法人证件OCR识别，
     * 将修改后信息与预留影印件不匹配的则更新OCR比对结果并通过【企业会员信息修改结果通知】，
     * 商户需根据OCR结果判断，是否需通过【影印件采集】接口，重新上传影印件。
     */
    @RequestMapping("/updateCompanyInfoResult")
    public ResponseEntity<String> updateCompanyResult(HttpServletRequest request,
                                                      @RequestBody(required = false) String data) throws UnsupportedEncodingException {

        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("修改企业信息回调:{}", openRequest.getBizContent());
        UpdateCompanyInfoResp updateCompanyInfoResp = JSON.parseObject(openRequest.getBizContent(), UpdateCompanyInfoResp.class);
        Integer status = allinpayCompanyService.getIdCardStatus(updateCompanyInfoResp.getOcrRegnumComparisonResult(), updateCompanyInfoResp.getOcrIdcardComparisonResult());
        companyAuditingService.updateCompanyInfoResult(updateCompanyInfoResp.getBizUserId(), status, updateCompanyInfoResp.getResult(), updateCompanyInfoResp.getFailReason());
        return ResponseEntity.ok(AllinpayConstant.NOTICE_SUCCESS);
    }

    /**
     * 影印件采集回调
     */
    @RequestMapping("/idCardCollectResult")
    public ResponseEntity<String> idCardCollectResult(HttpServletRequest request,
                                                      @RequestBody(required = false) String data) throws UnsupportedEncodingException {
        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("影印件回调：{}", openRequest.getBizContent());
        IdCardCollectResultResp idCardCollectResultResp = JSON.parseObject(openRequest.getBizContent(), IdCardCollectResultResp.class);
        allinpayCompanyService.deleteCache(Long.valueOf(idCardCollectResultResp.getBizUserId().substring(AllinpayConstant.SHOP_LENGTH)));
        CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(idCardCollectResultResp.getBizUserId());
        Integer status = allinpayCompanyService.getIdCardStatus(companyInfo.getOcrRegnumComparisonResult(), companyInfo.getOcrIdcardComparisonResult());
        shopDetailService.updateAllinpayIdCardStatus(idCardCollectResultResp.getBizUserId(), status);
        shopDetailService.removeShopDetailCacheByShopId(Long.valueOf(idCardCollectResultResp.getBizUserId().substring(AllinpayConstant.SHOP_LENGTH)));
        return ResponseEntity.ok(AllinpayConstant.NOTICE_SUCCESS);
    }

    /**
     * 签约账户提现协议回调
     */
    @RequestMapping("/signAcctProtocol")
    public ResponseEntity<String> signAcctProtocolResult(HttpServletRequest request,
                                                         @RequestBody(required = false) String data) throws UnsupportedEncodingException {

        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("签约账户提现协议回调：{}", openRequest.getBizContent());
        SignAcctProtocolResp signAcctProtocolResp = JSON.parseObject(openRequest.getBizContent(), SignAcctProtocolResp.class);
        if (Objects.equals(signAcctProtocolResp.getResult().toUpperCase(Locale.ROOT), AllinpayPayStatus.OK.value())) {
            if (signAcctProtocolResp.getBizUserId().contains(AllinpayConstant.USER)) {
                // 修改用户拓展信息(提现协议已签约)
                String userId = signAcctProtocolResp.getBizUserId().replace(AllinpayConstant.USER, "");
                logger.info("用户[{}]提现协议签约成功", userId);
                UserExtension userExtension = new UserExtension();
                userExtension.setUserId(userId);
                userExtension.setAllinpayProtocolSign(1);
                userExtensionService.updateByUserId(userExtension);
            } else if (signAcctProtocolResp.getBizUserId().contains(AllinpayConstant.SHOP)) {
                // 商家更新签约协议
                // 企业会员-“企业名称”“法人姓名”变更后，需重新签约。
                Long shopId = Long.valueOf(signAcctProtocolResp.getBizUserId().substring(AllinpayConstant.SHOP_LENGTH));
                CompanyInfo companyInfo = allinpayCompanyService.getCompanyInfo(signAcctProtocolResp.getBizUserId());
                // 签约类型 1.个人 2.法人 3.企业
                Integer signAcctType = Objects.equals(companyInfo.getCompanyName(), signAcctProtocolResp.getSignAcctName()) ? 3 : 2;
                shopDetailMapper.updateAcctProtocolNoByType(shopId, signAcctType, signAcctProtocolResp.getAcctProtocolNo());
                shopDetailService.removeShopDetailCacheByShopId(shopId);
            }
        }
        return ResponseEntity.ok(AllinpayConstant.NOTICE_SUCCESS);
    }

    /**
     * 设置支付密码回调
     */
    @RequestMapping("/setPayPwdResult")
    public ResponseEntity<String> setPayPwdResult(HttpServletRequest request,
                                                  @RequestBody(required = false) String data) throws UnsupportedEncodingException {
        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("设置支付密码回调内容: {}", openRequest.getBizContent());
        SetPayPwdResp setPayPwdResp = JSON.parseObject(openRequest.getBizContent(), SetPayPwdResp.class);
        // 更新用户拓展信息(支付密码已设置)
        if (Objects.equals(AllinpayPayStatus.OK.value(), setPayPwdResp.getStatus())) {
            String userId = setPayPwdResp.getBizUserId().replace(AllinpayConstant.USER, "");
            logger.info("用户[{}]设置支付密码成功", userId);
            UserExtension userExtension = new UserExtension();
            userExtension.setUserId(userId);
            userExtension.setAllinpayPayPwdSet(1);
            userExtensionService.updateByUserId(userExtension);
        }
        return ResponseEntity.ok(AllinpayConstant.NOTICE_SUCCESS);
    }

    /**
     * 修改支付密码回调
     */
    @RequestMapping("/updatePayPwdResult")
    public ResponseEntity<String> updatePayPwd(HttpServletRequest request,
                                               @RequestBody(required = false) String data) throws UnsupportedEncodingException {
        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("修改支付密码回调内容: {}", openRequest.getBizContent());
        return ResponseEntity.ok(AllinpayConstant.NOTICE_SUCCESS);
    }

    /**
     * 重置支付密码回调
     */
    @RequestMapping("/resetPayPwdResult")
    public ResponseEntity<String> resetPayPwd(HttpServletRequest request,
                                              @RequestBody(required = false) String data) throws UnsupportedEncodingException {
        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("重置支付密码回调内容: {}", openRequest.getBizContent());
        return ResponseEntity.ok(AllinpayConstant.NOTICE_SUCCESS);
    }

    /**
     * 修改绑定手机（密码校验版）
     */
    @RequestMapping("/updatePhoneByPayPwdResult")
    public ResponseEntity<String> updatePhoneByPayPwdResult(HttpServletRequest request,
                                                            @RequestBody(required = false) String data) throws UnsupportedEncodingException {
        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("修改绑定手机回调内容: {}", openRequest.getBizContent());
        UpdatePhoneByPayPwdResp updatePhoneResp = JSON.parseObject(openRequest.getBizContent(), UpdatePhoneByPayPwdResp.class);
        return ResponseEntity.ok(AllinpayConstant.NOTICE_SUCCESS);
    }

    /**
     * 提现申请
     */
    @RequestMapping("/withdrawApply")
    public ResponseEntity<String> withdrawApply(HttpServletRequest request,
                                                @RequestBody(required = false) String data) throws UnsupportedEncodingException {

        OpenRequest openRequest = allinpayConfig.validateAllinpayAndReturn(data, request);
        logger.info("提现回调内容: {}", openRequest.getBizContent());
        OrderResultNotice orderResultNotice = JSON.parseObject(openRequest.getBizContent(), OrderResultNotice.class);
        String failStr = "";
        if (Objects.equals(orderResultNotice.getStatus(), AllinpayPayStatus.ERROR.value())) {
            GetOrderStatusResp getOrderStatusResp = allinpayOrderService.getOrderStatus(new GetOrderStatusReq(orderResultNotice.getBizOrderNo()));
            failStr = getOrderStatusResp.getErrorMessage();
        }
        if (orderResultNotice.getBuyerBizUserId().contains(AllinpayConstant.SHOP)) {
            // 店铺提现回调
            shopWithdrawCashService.withdrawBack(orderResultNotice.getBizOrderNo(), orderResultNotice.getStatus(), orderResultNotice.getBuyerBizUserId(), failStr);
        } else {
            userWithdrawCashService.withdrawBack(orderResultNotice.getBizOrderNo(), orderResultNotice.getStatus(), failStr);
        }
        return ResponseEntity.ok(AllinpayConstant.NOTICE_SUCCESS);
    }
}
